const {listWaitOrders, cancelOrder, sendOrder, market_order_price} = require('./datasProcessor')

exports.cancelBadOrders = async ({base, quote, best_ask_price, best_bid_price}) => {
	const access_token = config.access_token
	const UserId = config.UserId
	const [error, orders] = await listWaitOrders(`${base.toUpperCase()}_${quote.toUpperCase()}`, access_token, UserId)
	if (error) return
	for (let order of orders) {
		if (order.Side == 'Sell' && order.InsertPrice <= best_ask_price) {
    		await cancelOrder({...order, access_token, UserId})
    	} 

    	if (order.Side == 'Buy' && order.InsertPrice >= best_bid_price) {
    		await cancelOrder({...order, access_token, UserId})
    	}
	}
}

exports.generate_depth = async ({base, quote, best_ask_price, best_bid_price, depthMinBuy, depthMinSell}) => {
	const Contract = `${base.toUpperCase()}_${quote.toUpperCase()}`
	const access_token = config.access_token
	const UserId = config.UserId
	const maxOrderNum = config.maxOrderNum
	const priceStepLimit = 0.001
	const priceMaxGap = maxOrderNum * priceStepLimit
	const [error, orders] = await listWaitOrders(Contract, access_token, UserId)
	if (error) return
	const buy_orders = orders.filter(item => item.Side === 'Buy').sort((pre, cur) => pre.InsertPrice - cur.InsertPrice)
	const sell_orders = orders.filter(item => item.Side === 'Sell').sort((pre, cur) => cur.InsertPrice - pre.InsertPrice)

	const bid_price_limit = best_bid_price * (1 - priceMaxGap)
	const ask_price_limit = best_ask_price * (1 + priceMaxGap)

	for (let i = 0; i < buy_orders.length; i++) {
		if (i > maxOrderNum || buy_orders[i].InsertPrice <= bid_price_limit || new Date() - new Date(buy_orders[i].InsertTime) > 3600000) {
			buy_orders.splice(i, 1)
			await cancelOrder({...buy_orders[i], access_token, UserId})
		}
	}

	for (let i = 0; i < sell_orders.length; i++) {
		if (i > maxOrderNum || sell_orders[i].InsertPrice >= ask_price_limit || new Date() - new Date(sell_orders[i].InsertTime) > 3600000) {
			sell_orders.splice(i, 1)
			await cancelOrder({...sell_orders[i], access_token, UserId})
		}
	}

	{
		const InsertPrice = best_bid_price
		let InsertVolume = depthMinBuy + Math.random() * depthMinBuy * 3
		await sendOrder({Contract, Side: 'Buy', InsertPrice, InsertVolume, access_token, UserId})
	}

	{
		const InsertPrice = best_ask_price
	    let InsertVolume = depthMinSell + Math.random() * depthMinSell * 3
	    await sendOrder({Contract, Side: 'Sell', InsertPrice, InsertVolume, access_token, UserId})
	}

	{
		const count_buy_orders = buy_orders.length
	    const minBuyPrice = buy_orders[count_buy_orders - 1] && buy_orders[count_buy_orders - 1].InsertPrice || best_bid_price
	    let priceAry = []
	    let volumeAry = []
	    const buyOrdersCount = parseInt(Math.random() * (maxOrderNum - count_buy_orders))
	    for (let i = 0; i < buyOrdersCount; i++) {
			const n = 1 + Math.random() * (maxOrderNum - 1)
	    	const rate = n * (priceStepLimit/2 + Math.random() * (priceStepLimit * 1.5 - priceStepLimit/2) )
	    	const InsertPrice = minBuyPrice * (1 - rate)
	    	priceAry.push(InsertPrice)

	    	let depthMaxBuy = depthMinBuy * 1000
	    	if (parseInt(Math.random() * 1000000) % 4 === 0 ) {
				depthMaxBuy > 1 ? '' : depthMaxBuy = config.btc_price * 4 / config.maxOrderNum / best_ask_price
			} 
			let InsertVolume = depthMinBuy + Math.random() * (depthMaxBuy - depthMinBuy)
			volumeAry.push(InsertVolume)
	    } 
	    
	    priceAry = priceAry.sort((pre, cur) => cur - pre)
	    volumeAry = volumeAry.sort((pre, cur) => pre - cur)
	    for (let i = 0; i < buyOrdersCount; i++) {
			await sendOrder({Contract, Side: 'Buy', InsertPrice: priceAry[i], InsertVolume: volumeAry[i], access_token, UserId})
	    }  
	}

	{
		const count_sell_orders = sell_orders.length
	    const maxSellPrice = sell_orders[count_sell_orders - 1] && sell_orders[count_sell_orders - 1].InsertPrice || best_ask_price
	    let priceAry = []
	    let volumeAry = []
	    const sellOrderCount = parseInt(Math.random() * (maxOrderNum - count_sell_orders))
	    for (let i = 0; i < sellOrderCount; i++) {
		    const n = 1 + Math.random() * (maxOrderNum - 1)
	    	const rate = n * (priceStepLimit/2 + Math.random() * (priceStepLimit * 1.5 - priceStepLimit/2) )
	    	const InsertPrice = maxSellPrice * (1 + rate)
	    	priceAry.push(InsertPrice)

	    	let depthMaxSell = depthMinSell * 1000
	    	if (parseInt(Math.random() * 1000000) % 4 === 0 ) {
				depthMaxSell > 1 ? '' : depthMaxSell = config.btc_price * 4 / config.maxOrderNum / best_ask_price
			} 
			let InsertVolume = depthMinSell + Math.random() * (depthMaxSell - depthMinSell)
			volumeAry.push(InsertVolume)
	    }

	    priceAry = priceAry.sort((pre, cur) => cur - pre)
	    volumeAry = volumeAry.sort((pre, cur) => cur - pre)
	    for (let i = 0; i < sellOrderCount; i++) {
		    await sendOrder({Contract, Side: 'Sell', InsertPrice: priceAry[i], InsertVolume: volumeAry[i], access_token, UserId})
	    }
	}
}

exports.generate_trade = async ({base, quote, best_ask_price, best_bid_price, trade_time_last}) => {
	if (Date.now() - trade_time_last < Math.random() * config.timeout * 1000) {
		return
	}
	LOG([`\n================== Trade Trade Trade ======================`])
	const Contract = `${base.toUpperCase()}_${quote.toUpperCase()}`
	const access_token = config.access_token
	const UserId = config.UserId

	const tradeMin = config.contractMap[base][2] / best_bid_price
	let tradeMax = config.contractMap[base][2] * config.maxOrderNum / best_bid_price

	if (parseInt(Math.random() * 1000000) % config.highTradeRandomBase === 0 ) {
		tradeMax < 1 ? tradeMax = 4 : ''
	}
	
	if (parseInt(Math.random() * 1000000) % config.highTradeRandomBase === 0 ) {
		tradeMax > 100 ? '' : tradeMax = config.btc_price * 2 / best_bid_price
		tradeMax < 1 ? tradeMax = 2 : ''
	}

	let InsertVolume = tradeMin + Math.random() * (tradeMax - tradeMin)
	// console.log(InsertVolume, trade_time_last)
	
	let [bitrabit_ask_price, bitrabit_bid_price] = [0, 0];

	[bitrabit_ask_price, bitrabit_bid_price] = await market_order_price(base, quote)

	let max_bid_price = Math.max(bitrabit_bid_price, best_bid_price)
    let min_ask_price = Math.min(bitrabit_ask_price, best_ask_price)
    if (min_ask_price < max_bid_price) [min_ask_price, max_bid_price] = [max_bid_price, min_ask_price]
	const InsertPrice = max_bid_price + Math.random() * (min_ask_price - max_bid_price)

	// console.log(bitrabit_ask_price, bitrabit_bid_price, min_ask_price, max_bid_price)
	let randomCount = 1 + parseInt(Math.random() * 1000000)
	if (randomCount % 2 === 0) {
		await sendOrder({Contract, Side: 'Sell', InsertPrice, InsertVolume, access_token, UserId})
		await sendOrder({Contract, Side: 'Buy', InsertPrice, InsertVolume, access_token, UserId})
	} else {
		await sendOrder({Contract, Side: 'Buy', InsertPrice, InsertVolume, access_token, UserId})
		await sendOrder({Contract, Side: 'Sell', InsertPrice, InsertVolume, access_token, UserId})
	}
	LOG([`================== Trade Trade Trade ======================\n`])
	return Date.now()
}

exports.getbtcprice = async () => {
	let price = 0
	try {
		const {body} = await Request.getAsync('https://www.chaobi.com:6443/quotation/lastall', {json: true})
		datas = body.data.filter(item => item.contract === 'BTC_USDT' )[0].data
		price = datas.split('`')[5]
	} catch (error) {
		console.log(error)
	}
	return price
}

exports.getContractInfo = async () => {
	try {
		const {body} = await Request.getAsync('https://www.chaobi.com:7443/contract/precision', {json: true})
		if (body && body.status) {
			for (let item of body.data) {
				let TransactionCode = item.TransactionCode
				let Ary = TransactionCode.split('_')
				if (Ary[1] === 'USDT') {
					config.contractMap[Ary[0].toLowerCase()] = [item.PricePrecision || 0, item.VolumePrecision || 0, (item.MinTradeVolume || 0) + 1]
				}
			}
			// console.log(config.contractMap)
		}
	} catch (error) {
		console.log(error)
	}
}